iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 6
0

通常數學不耐症
是因為公式中含有大量的符號
要克服這個
我認為最好的方法就是實例練習


假設我們現在想知道國中生罹患中二病的機率
抽查了 50 個班級,每班 10 個學生
結果如下:
https://ithelp.ithome.com.tw/upload/images/20200918/20130625T9wecYlJnG.png

假設每個學生罹患中二病的情況是獨立事件且罹患機率為 true_pi
我們可以假設我們所觀察的現象服從二項分配

我們現在猜測兩個機率 pred_pi_1 = 0.4, pred_pi_2 = 0.5
那我們要選擇哪一個模型比較好呢

首先分別看兩個猜測的分配與觀察到的圖形差異
https://ithelp.ithome.com.tw/upload/images/20200918/20130625lmVi3NLv6k.png https://ithelp.ithome.com.tw/upload/images/20200918/20130625bH3gvJTIEs.png

然後分別看分布的機率
prob_true = [0.0, 0.0, 0.02, 0.02, 0.04, 0.2, 0.24, 0.26, 0.14, 0.08, 0.0]
prob_pred_1 = [0.01, 0.04, 0.12, 0.21, 0.25, 0.2 , 0.11, 0.04, 0.01, 0.0, 0.0]
prob_pred_2 = [0.0, 0.01, 0.04, 0.12, 0.21, 0.25, 0.21, 0.12, 0.04, 0.01, 0.0]

利用這些分布分別去計算 KL 散度
以 prob_true 與 prob_pred_1 為例



prob_pred_1, prob_pred_2 中雖有些呈現是 0
但那是因為我只取到小數點第 2 位的結果,故其真實值非0
所以若在真實計算中,分母都是非 0

若遇到以下情況有約定值(可利用微積分驗證):

類似作法可做出
比較兩者後可知
參數的選擇 pi 應選 0.5 較好(KL散度越小越好)


執行程式碼如下

import random
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import entropy
import math

# 選擇數的公式
def nCr(n, r):
    f = math.factorial
    return f(n) / f(r) / f(n-r)

# 二項分配
def binomial_distribution(n, r, pi):
    return nCr(n, r)*(pi**r)*(1-pi)**(n-r)
    
# 真實機率
true_pi = 0.587

# 創造樣本
sample = [sum(1 for i in range(11) if random.random()<true_pi) for j in range(50)]
prob_obs = [sample.count(i)/50 for i in range(11)]

# 畫出觀察到的分配
plt.bar(np.arange(11), prob_obs)
plt.show()

# 猜測 pi,並依此計算機率
pred_pi_1 = 0.4
bi_dist_1 = [binomial_distribution(n = 10, r = r, pi = pred_pi_1) for r in range(11)]

pred_pi_2 = 0.5
bi_dist_2 = [binomial_distribution(n = 10, r = r, pi = pred_pi_2) for r in range(11)]

# 從圖形上看 true, pred 差異
plt.bar(np.arange(11), prob_obs, alpha = 0.3, color = 'red', label = 'true')
plt.bar(np.arange(11), bi_dist_1, alpha = 0.3, color = 'green', label = 'pred_pi_1 = 0.4')
plt.legend()
plt.show()

plt.bar(np.arange(11), prob_obs, alpha = 0.3, color = 'red', label = 'true')
plt.bar(np.arange(11), bi_dist_2, alpha = 0.3, color = 'green', label = 'pred_pi_2 = 0.5')
plt.legend()
plt.show()

# 計算 KL
# entropy(pk, qk=None, base=None, axis=0) : if qk = None, then compute entropy; if not None, compute KL
print('KL(true, pred_1) = ', entropy(prob_obs, bi_dist_1))
print('KL(true, pred_2) = ', entropy(prob_obs, bi_dist_2))

上一篇
[Day 4]什麼是相對熵
下一篇
[Day 6]MLL 與相對熵
系列文
主管可能很機車,但數學不會,數學不會就是不會:盡學渣之力說數學原理30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言